﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elderos.Highlight.Search;
using Elderos.Ontology;
using Elderos.Utils.Extensions;

namespace Elderos.Highlight.Rules
{
    [RankingRule("CommonParent", RuleType.LinkedEntities)]
    public class RuleCommonParent : RankingRule
    {
        private readonly int _usaID = int.Parse(ConfigurationManager.AppSettings["UsaID"]);

        public RuleCommonParent(IOntologyData ontology) : base(ontology)
        {}

        protected async override Task<Dictionary<TextEntity, IRuleResult>> InnerRank(HighlightResult highlightResult)
        {
            int attID = Ontology.Attributes.First(x => x.Name == "/location/location/containedby").ID;
            int[] entityIDs = highlightResult.Positions.SelectMany(x => x.EntitiesFlattened)
                                                        .Select(x => x.EntityID)
                                                        .Distinct()
                                                        .ToArray();

            var attRefs = await Ontology.GetAttRefsAsync(new[] {attID}, entityIDs);

            //key - entityID, value - entities contained by
            Dictionary<int, HashSet<int>> containingRelations = attRefs
                    .Select(x => new { x.EntityID, ContainedBy = x.ReferenceID })
                    .Where(x => x.ContainedBy != _usaID)
                    .GroupBy(x => x.ContainedBy)
                    .Where(x => x.Count() > 1)
                    .ToDictionary(x => x.Key, y => new HashSet<int>(y.Select(z => z.EntityID)));

            var results = new Dictionary<TextEntity, IRuleResult>();

            foreach (var entity in highlightResult.Positions.SelectMany(x => x.EntitiesFlattened))
            {
                var neighbours = new HashSet<int>();
                foreach (var containingRelation in containingRelations)
                {
                    if (containingRelation.Value.Contains(entity.EntityID))
                    {
                        neighbours.AddRange(containingRelation.Value);
                    }
                }

                neighbours.Remove(entity.EntityID);
                results.Add(entity, new ContiniousResult(Name, neighbours.Count));
            }

            return results;
        }

        public override IRuleResult EmptyResult
        {
            get { return new ContiniousResult(Name, 0);}
        }
    }
}
